4.12 排序
1、普通排序
排序是指顺列排序,目的是将一组无充的记录调整为有序的记录,在Excel中提供了可以设置不形态的排序方式。在pandas中可以使用df.sort_values()函数,此函数可以按行,按列排序,可以单列、多列排序,有自定义排序的功能。此功能可以在不添加辅助列,就能执行排序前做数据预处理。
df.sort_values(by, axis=0, ascending=True, inplace=True, kind=”quicksort”, na_position=”last”, ignore=False, key=None)
by :要排序的索引名称或索引名称列表
axis :排序方向,axis=0表示按行排序,axis=1表示按列排序,
ascending :默认为True,即升序排序
kind : 排名方法,一般忽略
na_postion :设定缺失值显示位置,默认为last,也可以设置等于first
ignore_index :是否重新设置表格索引
key :自定义排序函数
import
pandas
as
pd
path = r "D:\Pyobject2023\object\测试\素材\测试素材.普通排序.xlsx"
df = pd.read_excel(path, index_col =0)
print (df)
df.iloc[:, 2 :]=df.iloc[:, 2 :].sort_values( "D" , axis = 1 , ascending = False )
# 按指定某一行排列,所以指定行必须要有,另外排列的字段数据必须是同一数据类型
print (df)
返回:
规格 | 等级 | 报价1 | 报价2 | 数量 | |
---|---|---|---|---|---|
产品 | |||||
A | 20支/包 | 高级 | 20 | 35 | 100 |
B | 5去/包 | 中级 | 5 | 6 | 300 |
C | 150支/包 | 低级 | 100 | 100 | 120 |
D | 10支/包 | 中级 | 30 | 25 | 50 |
规格 | 等级 | 报价1 | 报价2 | 数量 | |
---|---|---|---|---|---|
产品 | |||||
A | 20支/包 | 高级 | 100 | 20 | 35 |
B | 5去/包 | 中级 | 300 | 5 | 6 |
C | 150支/包 | 低级 | 120 | 100 | 100 |
D | 10支/包 | 中级 | 50 | 30 | 25 |
import pandas as pd
path = r "D:\Pyobject2023\object\测试\素材\测试素材.普通排序.xlsx"
df = pd.read_excel(path, index_col=0)
print (df)
t=df.sort_values([ "报价1","报价2" ], ascending =[ True,False ])
print (t)
返回:
规格 | 等级 | 报价1 | 报价2 | 数量 | |
---|---|---|---|---|---|
产品 | |||||
A | 20支/包 | 高级 | 20 | 35 | 100 |
B | 5去/包 | 中级 | 100 | 6 | 300 |
C | 150支/包 | 低级 | 100 | 100 | 120 |
D | 10支/包 | 中级 | 30 | 25 | 50 |
规格 | 等级 | 报价1 | 报价2 | 数量 | |
---|---|---|---|---|---|
产品 | |||||
A | 20支/包 | 高级 | 20 | 35 | 100 |
D | 10支/包 | 中级 | 30 | 25 | 50 |
C | 150支/包 | 低级 | 100 | 100 | 120 |
B | 5去/包 | 中级 | 100 | 6 | 300 |
2、自定义排序(单列处理)
一般来说,被排列的列要求数据规范,但在实际工作中,往往被排序的列并不规范,需要重新将数据处理规范后再排序,如果遇到不能修改原数据的要求,则只能使用添加辅助列的方式来完成了,但有了df.sort.values()函数的key参数就可以不添加辅助列完美元解决这些问题。
import pandas as pd
path = r "D:\Pyobject2023\object\测试\素材\测试素材.普通排序.xlsx"
df = pd.read_excel(path, index_col =0)
print (df)
s1=df.规格.str.findall( "\d+" ).apply( lambda l:int(l[0]))
s2=df.规格.str.findall( "\d+" ).str[0].astype( "int" ) # 等同上一列
print (s2)
df1=df.sort_values( "规格" ,key= lambda s:s.str.findall( "\d+" ).str[0].astype( "int" ))
print (df1)
返回:
规格 | 等级 | 报价1 | 报价2 | 数量 | |
---|---|---|---|---|---|
产品 | |||||
A | 20支/包 | 高级 | 20 | 35 | 100 |
B | 5去/包 | 中级 | 100 | 6 | 300 |
C | 150支/包 | 低级 | 100 | 100 | 120 |
D | 10支/包 | 中级 | 30 | 25 | 50 |
产品 | |
---|---|
A | 20 |
B | 5 |
C | 150 |
D | 10 |
Name: 规格, dtype: int32
规格 | 等级 | 报价1 | 报价2 | 数量 | |
---|---|---|---|---|---|
产品 | |||||
B | 5去/包 | 中级 | 100 | 6 | 300 |
D | 10支/包 | 中级 | 30 | 25 | 50 |
A | 20支/包 | 高级 | 20 | 35 | 100 |
C | 150支/包 | 低级 | 100 | 100 | 120 |
2、自定义排序(多列处理)
如下列,根据每种产品的总支数做降序处理
import pandas as pd
path = r"D:\Pyobject2023\object\测试\素材\测试素材.普通排序.xlsx"
df = pd.read_excel(path) #,index_col=0 不能有,否则会报错
print (df)
s1=df.规格.str.extract( "(\d+)" , expand = False ).astype( "int" )*df.数量
print (s1)
df1=df.sort_values( "规格" ,
key= lambda s:s.str.extract( "(\d+)" , expand = False ).astype( "int" )*df.数量,
ascending = False )
print (df1)
返回:
产品 | 规格 | 等级 | 报价1 | 报价2 | 数量 | |
---|---|---|---|---|---|---|
0 | A | 20支/包 | 高级 | 20 | 35 | 100 |
1 | B | 5去/包 | 中级 | 100 | 6 | 300 |
2 | C | 150支/包 | 低级 | 100 | 100 | 120 |
3 | D | 10支/包 | 中级 | 30 | 25 | 50 |
0 | 2000 |
1 | 1500 |
2 | 18000 |
3 | 500 |
产品 | 规格 | 等级 | 报价1 | 报价2 | 数量 | |
---|---|---|---|---|---|---|
2 | C | 150支/包 | 低级 | 100 | 100 | 120 |
0 | A | 20支/包 | 高级 | 20 | 35 | 100 |
1 | B | 5去/包 | 中级 | 100 | 6 | 300 |
3 | D | 10支/包 | 中级 | 30 | 25 | 50 |
import pandas as pd
path = r "D:\Pyobject2023\object\测试\素材\测试素材.普通排序.xlsx"
df = pd.read_excel(path)
df.等级=df.等级.astype( "category" )
df.等级=df.等级.cat.reorder_categories([ "低级","中级","高级" ])
t=df.sort_values( "等级" )
print (t)
返回:
产品 | 规格 | 等级 | 报价1 | 报价2 | 数量 | |
---|---|---|---|---|---|---|
2 | C | 150支/包 | 低级 | 100 | 100 | 120 |
1 | B | 5去/包 | 中级 | 100 | 6 | 300 |
3 | D | 10支/包 | 中级 | 30 | 25 | 50 |
0 | A | 20支/包 | 高级 | 20 | 35 | 100 |